#ifndef FRACTIONS_H
#define FRACTIONS_H

#include <cmath>
#include <cassert>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>

class Fraction
{
private:
    int numerator;
    int denominator;

    int gcd(int a, int b);

    int lcm(int a, int b);

    void reduce();

public:
    std::string toString();

    Fraction();

    Fraction(int numerator, int denominator);

    Fraction(const Fraction &fr);

    explicit Fraction(const std::string &string);

    explicit Fraction(const double &df);

    explicit Fraction(const char *ch);

    Fraction &operator=(const Fraction &fraction);

    Fraction &operator=(const double &df);

    Fraction &operator=(const std::string &string);

    Fraction &operator=(const char *ch);

    Fraction operator+(const Fraction &fraction);

    Fraction operator+(const double &fraction);

    Fraction operator+(const int &fraction);

    Fraction operator-(const Fraction &fraction);

    Fraction operator*(const Fraction &fraction);

    Fraction operator/(const Fraction &fraction);

    friend std::ostream &operator<<(std::ostream &os, Fraction &fr);

    friend std::istream &operator>>(std::istream &is, Fraction &fr);

    Fraction operator+=(const Fraction &fr);

    Fraction operator+=(const double &db);

    friend Fraction operator+(const int &i, const Fraction &fr);
    friend Fraction operator-(const int &i, const Fraction &fr);
    friend Fraction operator*(const int &i, const Fraction &fr);
    friend Fraction operator/(const int &i, const Fraction &fr);
    friend Fraction operator-(const double &d, const Fraction &fr);
    friend Fraction operator/(const double &d, const Fraction &fr);
    friend Fraction operator+(const double &d, const Fraction &fr);

    friend Fraction operator*(const double &d, const Fraction &fr);
};

#endif // FRACTIONS_H
